
package com.joeshing.security.resourcedetails.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;

import com.joeshing.security.resourcedetails.Resource;
import com.joeshing.security.resourcedetails.ResourceDetails;
import com.joeshing.security.resourcedetails.ResourceDetailsService;

public class JdbcResourceDetailsServiceImpl extends JdbcDaoSupport implements ResourceDetailsService {

	private String resourcesByResourceNameQuery;
	private String resourcesByResourceTypeQuery;
	private String attributesByResourceNameQuery;
	private String rolePrefix = "";

	public String getRolePrefix() {
		return rolePrefix;
	}

	public void setRolePrefix(String rolePrefix) {
		this.rolePrefix = rolePrefix;
	}

	@Override
	public ResourceDetails getResource(String name) throws DataAccessException {
		List<ResourceDetails>  resources = loadResource(name);
		if(resources.size()==0){
			logger.error("Resource Not Found, The ResString : "+name);
			return null;
		}
		ResourceDetails resource = (ResourceDetails)resources.get(0);
		List<ConfigAttribute> attributes = loadResourceAttributes(name);
		if(attributes.size()==0){
			logger.error("Resource has no GrantedAuthority, The ResString : "+name);
			return null;
		}
		return new Resource(resource.getName(), resource.getType(), attributes);
	}
	
	 protected List<ResourceDetails> loadResource(String name) {
        return getJdbcTemplate().query(resourcesByResourceNameQuery, new String[] {name}, new RowMapper<ResourceDetails>() {
            public ResourceDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
                String name = rs.getString(1);
                String type = rs.getString(2);
                return new Resource(name, type, ResourceDetails.EMPTY_ATTRIBUTES);
            }
        });
	 }
	 
	 protected List<ConfigAttribute> loadResourceAttributes(String name) {
		 return getJdbcTemplate().query(attributesByResourceNameQuery, new String[] {name}, new RowMapper<ConfigAttribute>() {
			 public ConfigAttribute mapRow(ResultSet rs, int rowNum) throws SQLException {
				 String attribute = rs.getString(1);
				 return new SecurityConfig(rolePrefix+attribute);
			 }
		 });
	 }

	@Override
	public List<String> getResourceNames(String type) {
        return getJdbcTemplate().query(resourcesByResourceTypeQuery, new String[] {type}, new RowMapper<String>() {
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString(1);
            }
        });
	}

	public void setResourcesByResourceNameQuery(String resourcesByResourceNameQuery) {
		this.resourcesByResourceNameQuery = resourcesByResourceNameQuery;
	}

	public void setResourcesByResourceTypeQuery(String resourcesByResourceTypeQuery) {
		this.resourcesByResourceTypeQuery = resourcesByResourceTypeQuery;
	}

	public void setAttributesByResourceNameQuery(
			String attributesByResourceNameQuery) {
		this.attributesByResourceNameQuery = attributesByResourceNameQuery;
	}

}
